
#define MICROPY_PY_SYS_PLATFORM "xt804"
#define MICROPY_HW_BOARD_NAME   "HiLink-Core"
#define MICROPY_HW_MCU_NAME     "W806"

//
// <WM_W800参数区使用说明>(2MB, blksize=64KB, W806片内Flash只有1MB)
//      作用                          |       起始地址  |        W806  
//----------------------------------------------------------------------------------
//  OTA Param(4KB)                    |  0x08xFF000     |    ---
//  System Param(12KB)                |  0x08xFC000     |     |
//  User Area(>=944KB, when X >=1)    |  0x08110000     |     | -> 后512K作为磁盘区
//  Image Run Area(575KB)             |  0x08080400     |     |
//  Run Image Header(1KB)             |  0x08080000     |    ---
//  Image OTA Area(448KB)             |  0x08010000     |    程序保存在这里
//  SecBoot Image Area(55KB)          |  0x08002400     |    secboot firmware
//  SecBoot Image Header(1KB)         |  0x08002000     |    secboot header
//  RF data(8KB)                      |  0x08000000     |
//----------------------------------------------------------------------------------
//  W806只有1MB的片内FLASH, 这里将前500KB划分为估计区(实际可用512-55-1-8=448KB)
//  将后半段FLASH(512KB)作为磁盘区
//
//  通过SDK代码可知(综合W800系列寄存器手册),QFlash的页为256B, 扇区为4KB,每次可从FLASH
//  读取256字节, 支持任意位置读取; QFlash支持块擦除(32K, 64K), 也支持扇区擦除(4KB),
//  写入1个扇区(4KB)则以页的方式写入(每次写入256B), 合计写入4096/256=16次
//  
//  littlefs规定, 每个文件至少占用一个块, 若块为64KB则保存不了几个文件(512K/64K=8), 这里
//  假定块大小(擦除单位)为扇区大小(0x1000=4KB).

// 进入BOOT模式可用命令(按下BOOT不松手, 然后按下reset后松手reset, 最后松手BOOT)
// 21 0a 00 ef 2a 31 00 00 00 80 84 1e 00   - 波特率 1M
// 21 0a 00 97 4b 31 00 00 00 00 c2 01 00   - 波特率 115200
// 21 06 00 1b e7 3c 00 00 00               - 获取QFLASH ID和容量(0x14-> 1<<(0x14)=1MB)
// 21 06 00 c7 7c 3f 00 00 00               - 系统重启
// 21 0a 00 e2 25 32 00 00 00 02 00 fe 00   - 擦除FLASH(1MB)
// 21 0a 00 c3 35 32 00 00 00 02 00 fe 01   - 擦除FLASH(2MB, 只对801起作用)
//

//
// DMA通道分配：
// 后期W801的移植, DMA0, DMA1, DMA2(WIFI, BLE, PSRAM, CAP1不要)
// ================================================================== //
//  DMA0     DMA1    DMA2    DMA3    DAM4    DMA5   DMA6     DMA7     //
//           PSRAM   SDIO    SPI      I2C    I2S    CAP0     CAP1     //
// ===================================================================//

#define MICROPY_HW_ENABLE_STORAGE  (1)                    /* 使能FS */
#define MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE (1)      /* 使用片内FLASH作为FS */
#define MICROPY_HW_BLK_START  0x08080000                  /* 必须能被MICROPY_HW_BLK_SIZE整除 */
#define MICROPY_HW_BLK_END    0x08100000
#define MICROPY_HW_BLK_SIZE   (4096)                      /* 以扇区为单位进行擦除 */
#define MICROPY_HW_BLK_CNT   ((MICROPY_HW_BLK_END - MICROPY_HW_BLK_START) / MICROPY_HW_BLK_SIZE)
#define MICROPY_HW_FS_BLK_OFFS   0                        /* 文件系统, 块偏移, 实际块号=FLASH_PART1_START_BLOCK+MICROPY_HW_FS_BLK_OFFS */

//#define FLASH_BLOCK_SIZE           MICROPY_HW_BLK_SIZE                               /* 块大小 */
//#define FLASH_PART1_START_BLOCK    (MICROPY_HW_BLK_START / MICROPY_HW_BLK_SIZE)      /* 起始块位置 */
//#define FLASH_PART1_BLK_CNT        MICROPY_HW_BLK_CNT                                /* 块数量 */

// cache
#define MICROPY_HW_EN_CACHE   (1)           /* 该值为1表示配置cache加速(只配置读缓存), 听说W801同时配置读写缓存会炸 */

// I2C(mux SWJ)
#define MICROPY_HW_EN_I2C     (1)          /* 使能I2C模块 */
#define MICROPY_HW_I2C_SDA    PA4
#define MICROPY_HW_I2C_SCL    PA1

#if MICROPY_HW_EN_I2C && (MICROPY_HW_I2C_SDA == PA4 || MICROPY_HW_I2C_SCL == PA1)
#define MICROPY_HW_DIS_SWJ    (1)          /* I2C引脚和JTAG调试口复用, 关闭JTAG */
#endif


// PSRAM
#define MICROPY_HW_EN_PSRAM   (0)          /* 一般人可能用不到, 设置为可选 */

#if (MICROPY_HW_EN_PSRAM <= 0)
    #define MICROPY_HW_PSRAM_SIZE       0    
    #define MICROPY_HW_PSRAM_SIZE_LABEL 0
#else
    #define MICROPY_HW_PSRAM_SIZE (8*1024*1024)     /* PSRAM的大小 */
    #define MICROPY_HW_PSRAM_LABEL 8M               /* 设置cache, 不能加括号或双引号, 必须是2的幂次, 如4K, 256K, 1M, 64M */
#endif	

#define MICROPY_HW_PSRAM_CK   PA15    /* 后期PWM测试, 调整CK为PA15, PB0用于PWM0 */
#define MICROPY_HW_PSRAM_CS   PB27    /* PB1用于PWM1, PB13映射为PWM1不行 */
#define MICROPY_HW_PSRAM_D0   PB2
#define MICROPY_HW_PSRAM_D1   PB3
#define MICROPY_HW_PSRAM_D2   PB4
#define MICROPY_HW_PSRAM_D3   PB5

// I2S
#define MICROPY_HW_EN_I2S      (1)    /* 一般人用不到, 设置为可选 */
#define MICROPY_HW_I2S_MCLK    PA7
#define MICROPY_HW_I2S_BCLK    PB8
#define MICROPY_HW_I2S_LRCK    PB9
#define MICROPY_HW_I2S_DI      PB10
#define MICROPY_HW_I2S_DO      PB11



//
// 对于W801/W806的LSPI,读写寄存器(TXDATA, RXDATA)都是32bit的(即1个字), 读写各有8个字做缓存(8*4=32B,相当于FIFO),
// 有个特别的地方, LSPI的通道配置寄存器(CH_CFG)提供读写长度位（16bit），最大可传输65535个bit(按产生多少个sck脉冲进行定义)，故HAL库定义了
// BLOCK_SIZE=(8K-8), 若收发的字节数太多，分成若干块分批收发(比stm32更能折腾, 但HAL库已做好处理)。
//  
// LSPI的数据收发寄存器是32bit的，读写缓存各8个字，如果以小端模式发送数据，设置发送位数=2*8(bit), LSPI先发送TXDATA[0], 然后发TXDATA[1]；
// 如果是大端模式, 先发TXDATA[3], 然后发送TXDATA[2]。
//
// 注意：SPI配置为小端模式时，不需要其它操作；如果配置为大端模式需要将低位字节挪到高位字节（相当于将本地字节序转为网络字节序），这个问题
// 在DMA操作特别折腾（使用大端模式，传输数据不满足4字节对齐）
//
// SPI
#define MICROPY_HW_EN_LSPI        (1)          /* W80x里SPI叫LSPI, HSPI没什么用(W806只能作为从机) */

#define MICROPY_HW_LSPI_PRI       (4)          /* SPI中断 */
#define MICROPY_HW_LSPI_DMA_PRI   (3)          /* SPI DMA中断, 比SPI中断高, 不然在SPI中断里重置DMA, 刷不到DMA中断 */
#define MICROPY_HW_LSPI_DMA  DMA_Channel3      /* 使用DMA通道3进行数据的读写 */

#define MICROPY_HW_LSPI_MOSI   PB26
#define MICROPY_HW_LSPI_MISO   PB25
#define MICROPY_HW_LSPI_SCK    PB24
#define MICROPY_HW_LSPI_CS     PA0

// SDIO MMC
#define MICROPY_HW_EN_MMC      (1)     /* SDIO接口, 操作SD卡 */
#define MICROPY_HW_MMC_CLK     PA9
#define MICROPY_HW_MMC_CMD     PA10
#define MICROPY_HW_MMC_DATA0   PA11
#define MICROPY_HW_MMC_DATA1   PA12
#define MICROPY_HW_MMC_DATA2   PA13
#define MICROPY_HW_MMC_DATA3   PA14

// PSRAM
#if MICROPY_HW_EN_PSRAM > 0
#define MICROPY_HW_EN_UART2    (0)      /* 使能PSRAM后, UART2, UART4禁止,没有多余GPIO */
#define MICROPY_HW_EN_UART4    (0)
#else
#define MICROPY_HW_EN_UART2    (1)      /* 通用串口2 */
#define MICROPY_HW_UART2_PRI    3       /* 中断优先级, 0~15, 值越小优先级越高 */
#define MICROPY_HW_UART2_TX    PB2
#define MICROPY_HW_UART2_RX    PB3

#define MICROPY_HW_EN_UART4    (1)      /* 通用串口4 */
#define MICROPY_HW_UART4_PRI    3       /* 中断优先级, 0~15, 值越小优先级越高 */
#define MICROPY_HW_UART4_TX    PB4
#define MICROPY_HW_UART4_RX    PB5
#endif


// REPL关联串口
#define MICROPY_HW_REPL_UART        1       /* REPL关联串口(使能) */
#define MICROPY_HW_UART_REPL       (0)      /* UART(0)与REPL绑定, 不能machine.Uart(0, baud=115200)创建 */
#define MICROPY_HW_UART_REPL_RXBUF 256      /* UART0接收缓存的长度 */

// UART
#define MICROPY_HW_EN_UART0    (1)      /* 作为调试口, REPL串口 */
#define MICROPY_HW_UART0_PRI    3       /* 中断优先级, 0~15, 值越小优先级越高 */
#define MICROPY_HW_UART0_TX    PB19
#define MICROPY_HW_UART0_RX    PB20

#define MICROPY_HW_EN_UART1    (1)      /* 通用串口1 */
#define MICROPY_HW_UART1_PRI    3       /* 中断优先级, 0~15, 值越小优先级越高 */
#define MICROPY_HW_UART1_TX    PB6
#define MICROPY_HW_UART1_RX    PB7

#define MICROPY_HW_EN_UART3    (1)      /* 通用串口3 */
#define MICROPY_HW_UART3_PRI    3       /* 中断优先级, 0~15, 值越小优先级越高 */
#define MICROPY_HW_UART3_TX    PA5
#define MICROPY_HW_UART3_RX    PA6

#define MICROPY_HW_EN_UART5    (1)      /* 通用串口5 */
#define MICROPY_HW_UART5_PRI    3       /* 中断优先级, 0~15, 值越小优先级越高 */
#define MICROPY_HW_UART5_TX    PB18
#define MICROPY_HW_UART5_RX    PB17


// Timer
#define MICROPY_HW_TIM_PRI        (5)   /* Tim0_5共用同一个定时器中断, TIM0_5_IRQHandler */
#define MICROPY_HW_EN_TIMER0      (1)
#define MICROPY_HW_EN_TIMER1      (1)
#define MICROPY_HW_EN_TIMER2      (1)
#define MICROPY_HW_EN_TIMER3      (1)
#define MICROPY_HW_EN_TIMER4      (1)
#define MICROPY_HW_EN_TIMER5      (1)

// PWM
// 
// PWM输出时, 默认先输出低电平后输出高电平(不翻转电平时)
// PWM踩坑记录： 2022年1月29日, PWM1的GPIO remap会有点小问题, 部分IO还不能用于PWM1(哪怕手册说可以)
//               2022年1月30日, PWM的PNUM中断状态位bit[4:0]是个整体, 写非零值把5个PWM状态位都清零, 会有竞态风险(特别是中断可嵌套)
//                              弃用PNUM中断事件
//               2022年2月01日, PWM4安排在PB16, 如果用于CAP模式会有问题, 因为配置为输入三态模式, 必须加上拉或下拉电阻确定电平

#define MICROPY_HW_PWM_PRI        (6)       /* PWM的中断优先级, 不开中断, CAP0, CAP1(通道4)走DMA */
#define MICROPY_HW_CAP_BUF_SIZE    30       /* 输入捕获, 缓存大小 */

#define MICROPY_HW_EN_PWM_CH0     (1)       /* PWM0, 支持捕获功能, 经过调整PB0用于PWM, 原PB12废弃 */
#define MICROPY_HW_PWM_CH0        PB0
#define MICROPY_HW_CAP0_DMA  DMA_Channel6   /* PWM0用于输入捕获时, 使用DMA通道6进行传输 */

#define MICROPY_HW_EN_PWM_CH1     (1)       /* 经过测试, PB1用于PWM1没问题, 其它的有问题, 用PA11(记不清)?还有PB13, 电压一直是3.3V, 没卵用 */
#define MICROPY_HW_PWM_CH1        PB1

#define MICROPY_HW_EN_PWM_CH2     (1)       /* PWM2 */
#define MICROPY_HW_PWM_CH2        PB14

#define MICROPY_HW_EN_PWM_CH3     (1)       /* PWM3 */
#define MICROPY_HW_PWM_CH3        PB25

#define MICROPY_HW_EN_PWM_CH4     (1)       /* PWM4, 支持捕获功能 */
#define MICROPY_HW_PWM_CH4        PB16
#define MICROPY_HW_CAP1_DMA  DMA_Channel7   /* PWM4用于输入捕获时, 使用DMA通道7进行传输 */

// ADC
#define MICROPY_HW_EN_ADC3     (1)   /* ADC通道3 */
#define MICROPY_HW_ADC_CH3     PA3

#define MICROPY_HW_EN_ADC4     (1)   /* ADC通道4 */
#define MICROPY_HW_ADC_CH4     PA2    

// RTC relevant data
#define MICROPY_HW_RTC_YEAR     22
#define MICROPY_HW_RTC_MONTH     1
#define MICROPY_HW_RTC_DAY       1
#define MICROPY_HW_RTC_HOUR      12
#define MICROPY_HW_RTC_MINUTE    56  
#define MICROPY_HW_RTC_SECOND    32
#define MICROPY_HW_RTC_WEEKDAY   1   /* 2022-01-01 monday=1, sunday=0 */
#define MICROPY_HW_RTC_TIMEZONE  8


// GPIO
#define MICROPY_HW_GPIOA_PRI     (8) /* GPIO中断优先级 */
#define MICROPY_HW_GPIOB_PRI     (8)

//#define MICROPY_HW_GPIO_PA8    PA8
//#define MICROPY_HW_GPIO_PB12   PB12
//#define MICROPY_HW_GPIO_PB13   PB13
//#define MICROPY_HW_GPIO_PB15   PB15
//#define MICROPY_HW_GPIO_PB21   PB21
//#define MICROPY_HW_GPIO_PB22   PB22
//#define MICROPY_HW_GPIO_PB27   PB27